const ts = require("typescript")
const fs = require('fs');
const path = require('path');
// const zcss = require('./zcss');
// const zjs = require('./zjs');
// const zhtm = require('./zhtm');

const { typeofTagsMap } = require('./zjsdata.js');

const tempDir = path.join(__dirname, 'ztemp/');
var stat;
try {
    stat = fs.statSync(tempDir);
    if (!stat.isDirectory()) {
        fs.mkdirSync(tempDir);
    }
} catch(e) {
    fs.mkdirSync(tempDir);
}
const tempFile = path.join(tempDir +'noseenosee.ts');

function transformUsingTS(eCode, again) {
    fs.writeFileSync(tempFile, eCode);
    // console.log(tempFile);
    const fileNames = [tempFile];
    const options = {
        target: ts.ScriptTarget.ES2020,
        module: ts.ModuleKind.CommonJS,
        allowJs: true
    }

    // var program = ts.createProgram(fileNames, options);
    // var checker = program.getTypeChecker();

    const serviceHost = {
        getScriptFileNames: () => fileNames,
        getScriptVersion: () => '0',
        getScriptSnapshot: fileName => {
            if (!fs.existsSync(fileName)) {
              return undefined;
            }
            return ts.ScriptSnapshot.fromString(fs.readFileSync(fileName).toString());
        },
        getCurrentDirectory: () => process.cwd(),
        getCompilationSettings: () => options,
        getDefaultLibFileName: options => ts.getDefaultLibFilePath(options),
    }
    const ls = ts.createLanguageService(serviceHost, ts.createDocumentRegistry());

    function grammarTransformer() {
        return context => {
            return node => ts.visitNode(node, visit);

            function visit(node) {
                if (ts.isCallExpression(node)) {
                    // console.log(node);
                    // console.log(node.expression.escapedText);
                    if (node.expression.escapedText === '类型') {
                        return ts.factory.createTypeOfExpression(node.arguments[0]);
                    }
                    // switch (node.expression.escapedText) {
                        // case '类型':
                            // console.log(node);
                            // return ts.factory.createTypeOfExpression(node.arguments[0]);
                        
                        // case '中翻英_html':
                        //     return ts.factory.createStringLiteral(zhtm.transpile(node.arguments[0]));

                        // case '中翻英_css':
                        //     console.log(node);
                        //     return ts.factory.createStringLiteral(zcss.transpile(("{" + node.arguments[0].text + "}").slice(1, -1)));

                        // case '中翻英_js':
                        //     return ts.factory.createStringLiteral(zjs.transpile(node.arguments[0]));
                    
                        // default:
                            // break;
                    // }
                }

                // 其它节点保持不变
                return ts.visitEachChild(node, visit, context);
            }
        }
    }

    function typeofTagsTransformer() {
        return context => {
            return node => ts.visitNode(node, visit);

            function visit(node) {
                if (ts.isBinaryExpression(node) && (node.operatorToken.kind === ts.SyntaxKind.EqualsEqualsEqualsToken || node.operatorToken.kind === ts.SyntaxKind.ExclamationEqualsEqualsToken) && node.left.kind === ts.SyntaxKind.TypeOfExpression && node.right.kind === ts.SyntaxKind.StringLiteral) {
                    let literal = node.right.text;
                    // console.log(literal);
                    if (Object.keys(typeofTagsMap).includes(literal)) {
                        return ts.factory.createBinaryExpression(node.left, node.operatorToken, ts.factory.createStringLiteral(typeofTagsMap[literal]));
                    }
                }

                // 其它节点保持不变
                return ts.visitEachChild(node, visit, context);
            }
        }
    }

    function identTransformer() {
        return context => {
            return node => ts.visitNode(node, visit);

            function visit(node) {
                if (ts.isIdentifier(node) && node.text.match(/[\u4e00-\u9fa5]/)) {
                    // console.log(node);
                    // let symbol = checker.getSymbolAtLocation(node);
                    // // console.log(symbol);
                    // if (symbol && symbol.getJsDocTags() && symbol.getJsDocTags().length) {
                    //     // console.log(node.text, symbol.getJsDocTags(checker));
                    //     for (let tag of symbol.getJsDocTags()) {
                    //         if (tag.name === '英文') {
                    //             return ts.factory.createIdentifier(tag.text);
                    //         }
                    //     }
                    // }
                    /* 改用语言服务实现 */                    
                    let qInfo = ls.getQuickInfoAtPosition(tempFile, node.pos+1);
                    // console.log(node.text, ls.getReferencesAtPosition(tempFile, node.pos+1)); 
                    // console.log(node.text, qInfo);
                    if (qInfo && qInfo.tags && qInfo.tags.length) {
                        for (let tag of qInfo.tags) {
                            if (tag.name === '英文') {
                                return ts.factory.createIdentifier(tag.text);
                            }
                        }
                    }
                    return node;
                }

                /* if (ts.isCallExpression(node)) { // 还是放在 babel 中处理?
                    // console.log(node);
                    // console.log(node.expression.escapedText);
                    if (node.expression.escapedText === '类型') {
                        return ts.factory.createTypeOfExpression(node.arguments[0])
                    }
                    // return node;
                } */

                /* if (ts.isBinaryExpression(node) && (node.operatorToken.kind === ts.SyntaxKind.EqualsEqualsEqualsToken || node.operatorToken.kind === ts.SyntaxKind.ExclamationEqualsEqualsToken) && node.left.kind === ts.SyntaxKind.TypeOfExpression && node.right.kind === ts.SyntaxKind.StringLiteral) {
                    let literal = node.right.text;
                    console.log(literal);
                    if (Object.keys(typeofTagsMap).includes(literal)) {
                        return ts.factory.createBinaryExpression(node.left, node.operatorToken, ts.factory.createStringLiteral(typeofTagsMap[literal]));
                    }
                } */

                // 其它节点保持不变
                return ts.visitEachChild(node, visit, context);
            }
        }
    }

    const opts = {
        compilerOptions: {
            strict: false,
            target: ts.ScriptTarget.Latest,
            // lib: ['es6', 'dom'] // 在这里可以指定编译所要包含的库? 须关注 tsconfig.json 的配置选项
            // newLine:  0 // 似乎无法保留原始换行信息, 什么作用?
        },
    };
    
    var result;
    if (again) {
        result = ts.transpileModule(eCode, {
            transformers: { before: [identTransformer()] },
            ...opts
        });
    } else {
        result = ts.transpileModule(eCode, {
            transformers: { before: [grammarTransformer(), typeofTagsTransformer()], after: [identTransformer()] },
            ...opts
        });
    }

    // console.log(result.outputText);
    return result.outputText.replace("// import Vue from 'vue'", "import Vue from 'vue'");
}

module.exports = {
    transformUsingTS
}